package no.cicero.testframework.reporting.reports;

import no.cicero.testframework.reporting.Reporting;
import no.cicero.testframework.reporting.ReportingTestCase;
import no.cicero.testframework.reporting.ReportingUseCase;
import org.apache.commons.io.FileUtils;

import java.io.*;

public class HtmlConsolidatedReport extends AbstractReport{
	private static final String FILES_FOLDER_CSS = "css";
	private static final String FILES_CSS = "style.css";
	
    private Reporting reporting;

    private PrintWriter reportWriter;

    private StringBuilder contentBuffer;
    private StringBuilder ucBuffer;
    private StringBuilder tcBuffer;
    private StringBuilder reportBuffer;

    private static String HEADER = "" +
        "<head>" +
        "    <title></title>" +
        "    <link rel='stylesheet' type='text/css' href='css/style.css' />" +
        "</head>" +
        "<body>" +
        "    <div id='main'>" +
        "        <div class='logo'>" +
        "            <h1>Test Report</h1>" +
        "            <h2>Cicero Budget Model</h2>" +
        "            <h3>Version 1.0</h2>" +
        "        </div>" +
        "        <div class='content'>" +
        "            This report contains aggregated data about quantity of passed / failed test cases, coverage and statistical data";

    private static String FOOTER = "" +
        "        </div> " +
        "        <div class='footer-logo'></div>" +
        "    </div>" +
        "</body>" +
        "</html>";

    public HtmlConsolidatedReport(File outputDirectory, File templateDirectory) throws IOException {
        this.reportWriter = generateFilesStructure(outputDirectory, templateDirectory);
    }

	@Override
	public void reportStarted(Reporting reporting) throws IOException {
		this.reporting = reporting;

        reportBuffer = new StringBuilder();
        contentBuffer = new StringBuilder();
        reportBuffer.append(HEADER);
    }

	@Override
	public void reportFinished() {
        reportBuffer.append("" +
                "       <div class='header'>\n" +
				"           <h3>Total Results:</h3>\n"+
				"               <div class='numbers'>Total steps run:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='color:blue'>"+reporting.getTotalStepsCount()+"</span></div>\n"+
				"               <div class='numbers'>Total steps failed:&nbsp;&nbsp; <span style='color:red'>"+reporting.getFailedStepsCount()+"</span></div>\n"+
                "       </div>");
        reportBuffer.append(contentBuffer);
        reportBuffer.append(FOOTER);
        reportWriter.println(reportBuffer);
        reportWriter.close();

        contentBuffer = null;
        reportBuffer = null;
		reporting = null;
    }

	@Override
	public void useCaseStarted(ReportingUseCase useCase) {
        ucBuffer = new StringBuilder();
        ucBuffer.append("			" +
                "       <div class='header'>\n" +
				"           <h3>"+ useCase.getUseCaseShortDescription() + "</h3>\n" +
				"           <div class='description'>" + useCase.getUseCaseDescription() + "</div>\n");
    }

	@Override
	public void useCaseSucceeded(ReportingUseCase useCase) {
        endUseCase(useCase);
    }

	@Override
	public void useCaseFailed(ReportingUseCase useCase, Exception ex) {
		ucBuffer.append(
			"           <div class='numbers' style='color:red'>FAILED" + ex.getMessage() + "</div>\n" +
			"      </div>\n"
		);
        endUseCase(useCase);
	}

	@Override
	public void testCaseStarted(ReportingTestCase testCase) throws IOException {
        if (tcBuffer == null) {
            tcBuffer = new StringBuilder();

            tcBuffer.append("" +
                "       <div class='table'>\n" +
				"           <table cellpadding='0' cellspacing='0'>\n" +
				"               <tr id='header'>\n" +
                "                   <td class='col1'>Test case name</td>\n" +
				"                   <td class='col2'>Short Description</td>\n" +
				"                   <td class='col3'>Total Steps</td>\n" +
				"                   <td class='col4'>Total Failed</td>\n" +
				"               </tr>\n");
        }
    }

	@Override
	public void testCaseSucceeded(ReportingTestCase testCase) {
        String classType = (testCase.getFailedStepsCount() == 0) ? "" : "red";
        endTestCase(testCase, classType);
    }

	@Override
	public void testCaseFailed(ReportingTestCase testCase, Exception ex) {
        endTestCase(testCase, "red");
	}

	private void endTestCase(ReportingTestCase testCase, String classType) {
		tcBuffer.append(
			"	" +
			"               <tr>\n" +
			"                   <td>" + testCase.getTestCaseName() + "</td>\n" +
			"                   <td>" + testCase.getTestCaseDescription() + "</td>\n" +
			"                   <td class='digit'>" + testCase.getTotalStepsCount() + "</td>\n" +
			"                   <td class='digit " + classType + "'>" + testCase.getFailedStepsCount() +
			"</td>\n" +
			"               </tr>\n"
		);
	}

	private void endUseCase(ReportingUseCase useCase) {
		ucBuffer.append(
			"           <div class='numbers'>Total steps run:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='color:blue'>" + useCase.getTotalStepsCount() + "</span></div>\n" +
			"           <div class='numbers'>Total steps failed:&nbsp;&nbsp; <span style='color:red'>" + useCase.getFailedStepsCount() + "</span></div>\n" +
			"      </div>\n"
		);
		contentBuffer.append(ucBuffer);
		contentBuffer.append(tcBuffer);
		contentBuffer.append(
			"           </table>\n" +
			"       </div>\n"
		);
		tcBuffer = null;
		ucBuffer = null;
	}

    private static PrintWriter generateFilesStructure(File dir, File templateDir) throws IOException {
        File css = new File(dir,FILES_FOLDER_CSS);
        FileUtils.forceMkdir(css);

		File file;

		file = new File(templateDir, FILES_CSS);
		if(file.exists())
			FileUtils.copyFileToDirectory(file, css);

		file = new File(templateDir, "logo.jpg");
		if(file.exists())
			FileUtils.copyFileToDirectory(file, css);

		file = new File(templateDir, "footer_logo.jpg");
		if(file.exists())
		    FileUtils.copyFileToDirectory(file, css);


        File mainFrame = new File(dir, "consolidated_report.html");
        return new PrintWriter(new BufferedWriter(new FileWriter(mainFrame)));
    }

}
